/***
 * File  	: Triangle.java
 * Subject	: Defines a triangle to be drawn
 * Author 	: Isaac Parenteau
 * Date		: March 30th, 2010
 */
package src.project.koch;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;

import javax.microedition.khronos.opengles.GL10;

public class Triangle {
	
	private float[] a;
	private float[] b;
	private float[] c;
	private float red = 1.0f;
	private float blue = 1.0f;
	private float green = 1.0f;
	private float alpha = 1.0f;

	private short[] indices = {0, 1, 2}; //Indicates the order indices to draw
	private int verts = 3; //Number of vertices
	private ShortBuffer indiceBuffer;
	private FloatBuffer vertexBuffer;
	
	
	/**
	 * Default Constructor
	 */
	public Triangle(){ this(new float[]{0,0,0}, new float[] {0,0,0}, new float[]{0,0,0});}
	/**
	 * Constructor
	 * @param pointA
	 * @param pointB
	 * @param pointC
	 */
	public Triangle(float[] pointA, float[] pointB, float[] pointC)
	{
		init(pointA, pointB, pointC);
	}
	
	/**
	 * Draws the triangle on the surface
	 * @param gl
	 */
	public void Draw(GL10 gl)
	{		
		gl.glColor4f(red, green, blue, alpha); //Sets the color of the triangle
		
		//Generates a pointer to the vertex buffer to draw the points on screen
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
		//Draws the element on screen using GL_TRIANGLES the indiceBuffer 
		//determines which order to draw and connect the triangles
		gl.glDrawElements(GL10.GL_TRIANGLES, verts,
				GL10.GL_UNSIGNED_SHORT, indiceBuffer);
	}
	
	/**
	 * Sets the color of the triangle
	 * @param r
	 * @param g
	 * @param b
	 */
	public void SetColor(float r, float g, float b)
	{
		SetColor(r, g, b, 1.0f);
		
	}
	
	/**
	 * Sets the color of the triangle with alpha value
	 * @param r
	 * @param g
	 * @param b
	 * @param a
	 */
	public void SetColor(float r, float g, float b, float a){
		
		red = r;
		green = g;
		blue = b;
		alpha = a;
	}
	
	/**
	 * Initializes the triangle
	 * @param pointA
	 * @param pointB
	 * @param pointC
	 */
	private void init(float[] pointA, float[] pointB, float[] pointC) {
		a = pointA;
		b = pointB;
		c = pointC;
		
		float[] coords = toCoords(a, b, c);
		
		//Have to create a buffer for the vertex buffer
		//Since a float is 4 bytes and there are 3 floats per float array
		//and 3 vertices for a triangle then we have to allocate 36 bytes to the buffer
		// 3 * 4 * 3
		ByteBuffer vbb = ByteBuffer.allocateDirect(verts * 12);
		vbb.order(ByteOrder.nativeOrder()); //returns the platforms native order (Little Endian or Big endian)
		vertexBuffer = vbb.asFloatBuffer(); //Casts the buffer as a float buffer
		
		//Same explanation as above but there are only two bytes for a short and 3 points 
		//for the indices
		ByteBuffer ibb = ByteBuffer.allocateDirect(verts * 2);
		ibb.order(ByteOrder.nativeOrder());
		indiceBuffer = ibb.asShortBuffer();
		
		//Puts the coordinates of the triangle in the vertexBuffer
		vertexBuffer.put(coords);
		//Puts the indices in the indices buffer
		indiceBuffer.put(indices);
		
		//Sets the position of hte pointer for both vertices and indice buffer
		//at the beginning
		vertexBuffer.position(0);
		indiceBuffer.position(0);
		
	}
	/**
	 * Converts the three given points to a coordinate system that 
	 * vertexBuffer understands
	 * @param pointA
	 * @param pointB
	 * @param pointC
	 * @return
	 */
	private float[] toCoords(float[] pointA, float[] pointB, float[] pointC) {
		
		float[] c = {pointA[0], pointA[1], 0,
					 pointB[0], pointB[1], 0,
					 pointC[0], pointC[1], 0
		};
		return c;
	}
}
